class WebsocketState {
  static CONNECTING = 0;
  static OPEN = 1;
  static CLOSING = 2;
  static CLOSED = 3;
  constructor() {}
}

export default class Websocket {
  constructor(option) {
    this.option = option
    this.sendMessageCallBack = []
    this.isReconnect = false
    this.delayConnectTime = null
    this.recevier = null
    // 心跳机制
    this.interval = this.option.heartBeat.sendInterval
    this.serverTimeout = this.option.heartBeat.receiveInterval
    this.intervalTimer = null
    this.serverTimer = null
    // 创建ws
    this.createWs()
  }

  static getInstance(option) {
    return new Websocket(option = {
      url: 'ws://47.242.25.96:10000/websocket/quote?_=1607675853653&_s=d1e829d321b235cbc31a0539cd5a986d'
    })
  }

  // 心跳机制
  setHearBeat() {
    this.intervalTimer && clearTimeout(this.intervalTimer)
    this.serverTimer && clearTimeout(this.serverTimer)
    this.intervalTimer = setTimeout(() => {
      // 这里发送一个心跳，后端收到后，返回一个心跳消息，
      // onmessage拿到返回的心跳就说明连接正常
      this.ws.send(JSON.stringify({ sub: 'ping' }))
      this.serverTimer = setTimeout(() => {
        this.ws.close()
      }, this.serverTimeout)
    }, this.interval)
  }

  createWs() {
    if ('WebSocket' in window) {
      this.ws = new WebSocket(this.option.url)
      this.initBind()
    } else {
      console.warn('浏览器不支持')
    }
  }

  initBind() {
    this.ws.onopen = this.open.bind(this)
    this.ws.onmessage = this.onmessage.bind(this)
    this.ws.onclose = this.onclose.bind(this)
    this.ws.onerror = this.onerror.bind(this)
  }

  // 重连
  reconnect() {
    console.warn('重新连接')
    if (this.isReconnect) return
    this.isReconnect = true
    // 没连接上会一直重连，设置延迟避免请求过多
    this.delayConnectTime && clearTimeout(this.delayConnectTime)
    this.delayConnectTime = setTimeout(() => {
      this.createWs(this.option.url)
      this.isReconnect = false
    }, 4000)
  }

  // 开启
  open() {
    // 开启回调
    this.sendMessageCallBack.forEach(data => {
      this.ws.send(data)
    })

    if (this.option.heartBeat.enable) {
      this.setHearBeat()
    }
  }

  // 接受
  onmessage(data) {
    if (data === 'ok') return
    if (this.option.heartBeat.enable) {
      this.setHearBeat()
    }
    if (!this.recevier) return
    this.recevier(data)
  }

  onMessage(recevier) {
    this.recevier = recevier
  }

  // 关闭
  onclose() {
    // 重新连接
    this.reconnect()
  }

  // 报错
  onerror() {
    // 重新连接
    this.reconnect()
  }

  // 发送消息
  send(data) {
    if (data.sub === 'del') {
      if (this.sendMessageCallBack.length) {
        this.sendMessageCallBack.forEach((item, index) => {
          if (JSON.parse(item).type === data.type) {
            this.sendMessageCallBack.splice(index, 1)
          }
        })
      }
    }
    data = JSON.stringify(data)
    if (this.ws.readyState === WebsocketState.CONNECTING) {
      this.sendMessageCallBack.push(data)
    }
    if (this.ws.readyState === WebsocketState.OPEN) {
      this.ws.send(data)
    }
  }
}
